#ifndef _MODEL_H_
#define _MODEL_H_
#include <GL/glut.h>

#include <math.h>
#include <string>
#include <vector>

void rotatePoint(float ux, float uy, float uz, float angle, float &x, float &y,
                 float &z);

class Model {
private:
    // correspond to texname in TextureManager
    std::string texname = "";
    unsigned texid = 0;

    // parameter for translate/scale/rotate
    float translate[3] = {0, 0, 0};
    float scale[3] = {1, 1, 1};
    float rotate[3] = {0, 1, 0};
    float angle = 0;

    // parameter for material
    float ambient[4] = {0.2, 0.2, 0.2, 1.0};
    float diffuse[4] = {0.8, 0.8, 0.8, 1.0};
    float specular[4] = {0.633, 0.727811, 0.633, 1.0};
    float shininess[1] = {78};
    // float specular[4] = {0.0, 0.0, 0.0, 1.0};
    // float shininess[1] = {0.0f};

    // parameter for edge detection
    float boundingbox[8][3] = {{-1, 1, 1},  {1, 1, 1},   {1, -1, 1},
                               {-1, -1, 1}, {-1, 1, -1}, {1, 1, -1},
                               {1, -1, -1}, {-1, -1, -1}};
    float newboundingbox[8][3] = {{-0.5, 0.5, 0.5},  {0.5, 0.5, 0.5},
                                  {0.5, -0.5, 0.5},  {-0.5, -0.5, 0.5},
                                  {-0.5, 0.5, -0.5}, {0.5, 0.5, -0.5},
                                  {0.5, -0.5, -0.5}, {-0.5, -0.5, -0.5}};
    // edge[0][1] x_min, edge[0][2] x_max
    float edge[3][2];

    virtual void drawCoordinates() = 0;
    void modifyBoundingbox();

public:
    bool isHit(float x, float y, float z);

    virtual void draw();

    /*-----------function for saving object-----------*/
    virtual void getObject(std::vector<std::vector<GLfloat>> &vSets,
                           std::vector<std::vector<GLfloat>> &vtSets,
                           std::vector<std::vector<GLfloat>> &vnSets,
                           std::vector<std::vector<GLint>> &fSets);

    /*-----------function for material setting-----------*/
    void setAmbient(float r, float g, float b, float a);

    void getAmbient(float &r, float &g, float &b, float &a);

    void setDiffuse(float r, float g, float b, float a);

    void getDiffuse(float &r, float &g, float &b, float &a);

    void setSpecular(float r, float g, float b, float a);

    void getSpecular(float &r, float &g, float &b, float &a);

    void setShininess(float s);

    void getShininess(float &s);

    /*-----------function for translate/scale/rotate setting-----------*/
    void setTranslate(float x, float y, float z);

    void getTranslate(float &x, float &y, float &z);

    void setScale(float x, float y, float z);

    void getScale(float &x, float &y, float &z);

    void setRotate(float angle, float x, float y, float z);

    void getRotate(float &angle, float &x, float &y, float &z);

    /*-----------function for texture setting-----------*/
    /*
    void setTexture(const std::string &texname){
        this->texname.assign(texname);
    }

    void resetTexture(){
        this->texname.assign("");
    }

    std::string getTexture(){
        return this->texname;
    }
    */

    void setTexture(unsigned texid);

    void resetTexture();

    unsigned getTexture();
};

#endif
